/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/
#include "pch.h"
#include <baja/transition_tracking/transition_tracking_service.h>
#include <baja/transition_tracking/transition_tracking_helpers.h>
#include <journal/models/photo_model.h>
#include <journal/models/photo_model_transitions.h>

using namespace journal::model;

namespace bt = baja::transition_tracking;

photo_model_transition::photo_model_transition()
{
}

b::uint32 photo_model_transition::transitionType(void)
{
    return photo_model_transition_type::updateTransition;
}

void photo_model_transition::dump()
{
}

void photo_model::undoSelfAction(
    const std::shared_ptr<bt::itransition_parameters>& transitionParameters)
{
    DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
        boost::wformat(L"photo_model::undoSelfAction() : model id = %i") %
        _photoId
        );

    switch (transitionParameters->transitionType())
    {
        case readyEventTransition:
            {
                DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                    boost::wformat(L"photo_model::undoSelfAction() : model id = %i : undo ready event") %
                    _photoId
                    );
            }

            // we don't need to tell anybody that we are no longer ready.

            // we should mark it for deletion!!

            break;
        case updateTransition:
            {
                DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                    boost::wformat(L"photo_model::undoSelfAction() : model id = %i : undo update") %
                    _photoId
                    );

                std::shared_ptr<photo_model_transition> p =
                    std::dynamic_pointer_cast<photo_model_transition>(transitionParameters);

                this->setAllAttributes(
                    p->_state0.mediaFileId,
                    p->_state0.localStorageFile,
                    p->_state0.localStorageFileStream,
                    p->_state0.scale,
                    p->_state0.position,
                    p->_state0.angle);

                this->firePhotoMovedEvent();
            }
            break;
        case notReadyEventTransition:
            {
                DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                    boost::wformat(L"photo_model::undoSelfAction() : model id = %i : undo not ready") %
                    _photoId
                    );

                this->markReady();
            }
            break;
    }
}

void photo_model::redoSelfAction(
    const std::shared_ptr<bt::itransition_parameters>& transitionParameters)
{
    DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
        boost::wformat(L"photo_model::redoSelfAction() : model id = %i") %
        _photoId
        );

    switch (transitionParameters->transitionType())
    {
        case updateTransition:
            {
                DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                    boost::wformat(L"photo_model::redoSelfAction() : model id = %i : redo update") %
                    _photoId
                    );

                std::shared_ptr<photo_model_transition> p =
                    std::dynamic_pointer_cast<photo_model_transition>(transitionParameters);

                this->setAllAttributes(
                    p->_state1.mediaFileId,
                    p->_state1.localStorageFile,
                    p->_state1.localStorageFileStream,
                    p->_state1.scale,
                    p->_state1.position,
                    p->_state1.angle);

                this->firePhotoMovedEvent();

            }
            break;
        case readyEventTransition:
            {
                DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                    boost::wformat(L"photo_model::redoSelfAction() : model id = %i : redo self ready event") %
                    _photoId
                    );

                this->markReady();
            }
            break;
        case notReadyEventTransition:
            DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO,
                boost::wformat(L"photo_model::undoSelfAction() : model id = %i : undo deactivate") %
                _photoId
                );

            // no-op

            break;
    }
}

void photo_model::registerUpdate(
    const b::Boolean& newActive,
    const std::shared_ptr<baja::storage::istorage_file>& newLocalStorageFile,
    const std::shared_ptr<b::imemory_stream>& newLocalStorageFileStream,
    const b::float32& newScale,
    const m::point2d& newPosition,
    const b::float32& newAngle
    )
{
    DEBUG_CONSOLE_TRACE_TAG(TRACE_TAG_UNDO_REDO, L"photo_model::registerUpdate()");

    bt::transition_context tc(constants::undoRedoService());

    std::shared_ptr<photo_model_transition> transition = std::make_shared<photo_model_transition>();

    // to undo
    transition->_state0.active = _active;
    transition->_state0.mediaFileId = _mediaFileId;
    transition->_state0.localStorageFile = _localStorageFile;
    transition->_state0.localStorageFileStream = _localStorageFileStream;
    transition->_state0.scale = _scale;
    transition->_state0.position = _position;
    transition->_state0.angle = _angle;

    // to redo
    transition->_state1.active = newActive;
    transition->_state1.mediaFileId = _mediaFileId;
    transition->_state1.localStorageFile = newLocalStorageFile;
    transition->_state1.localStorageFileStream = newLocalStorageFileStream;
    transition->_state1.scale = newScale;
    transition->_state1.position = newPosition;
    transition->_state1.angle = newAngle;

    constants::undoRedoService()->addTransition(transitionPath(), std::dynamic_pointer_cast<bt::itransition_parameters>(transition));
}